-
Notifications
You must be signed in to change notification settings - Fork 2
Feautre/add input fields to searchbar #689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feautre/add input fields to searchbar #689
Conversation
…n about behaviour
…is triggered This let the user know, that this input is not displayed in the current search.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the DatePickerComponent should be less concerned with the search bar functionality.
To keep up/down arrow navigation functionality I think it would be fine to use a capture phase event handler (https://svelte.dev/tutorial/svelte/capturing) in the search bar drop down to intercept up and down arrows before they even reach the text input using event.stopPropagation(). For numbers this would be fine in my opinion. I don't consider the up/down arrow to increment/decrement numbers important. I hope the date picker calendar arrow key navigation would not break.
I think you could use a similar strategy for detecting focus without touching the DatePickerComponent. Or alternatively just add a onfocus prop to the DatePickerComponent and handle everything else outside of the component.
|
|
||
| export default defineConfig([ | ||
| globalIgnores(["dist", "book/book", "docs/assets"]), | ||
| globalIgnores(["dist", "book", "docs/assets"]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I would want to lint the book markdown files. Can we fix the issues without disabling linting of those files completely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. but book/book doesn't exist anywhere, so this was unnecessary, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you install mdbook and build the book locally it generates the HTML files there.
monitor performance with big catalogues
timakro
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code in the search bar component looks much better now. And great that you added regex escaping to the search highlighting.
Do you think we can move some of the search bar and focus handling out of the input components? Maybe you can try my suggestion to intercept the arrow keys before the input components receive them. But I haven't thought a lot about that so I understand if you decide to stick with the current approach where you press escape to back out of the input component and then use the arrow keys.
| let inside: boolean = $state(false); | ||
| function handleClickInside(): void { | ||
| inside = true; | ||
| } | ||
| function handleClickOutside(): void { | ||
| if (!inside) { | ||
| autoCompleteOpen = false; | ||
| } | ||
| inside = false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these click handlers needed? I tried without them and didn't noticed a difference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should have handled the click onto an input element of the options but didn't work because the inside check was missing in handleFocusOut(). Added it and now it works as intended: when the click is outside the form elements but still inside of the input element it won't close.
| } | ||
| let searchBarContainer: HTMLElement; | ||
| let optionsList: HTMLUListElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unused
| onmousedown={() => | ||
| addInputValueToStore( | ||
| inputOption, | ||
| extractTargetGroupFromInputValue(), | ||
| )} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this do anything? The NumberInputComponent adds the item to the query itself.
I'm always careful when it comes to altering browser native behaviour. the user will expect the form fields to work the same way throughout the application. if we make that change, the input will behave differently from the ones in the catalogue. also it's a behaviour known to users for as long as they use the internet 😅 But maybe the convenience for the user is high enough to make that change. I guess this would come down to a short user test. I will recruit some non-IT-people. |
I tried from the beginning and failed miserably 😄. 100% open to elegant solutions. |
I agree. In this case I think it might be worth it to prioritize the arrow keys but I'm not dead set on it.
I'd try to use a capture phase event handlers (https://svelte.dev/tutorial/svelte/capturing) on the input components to catch the |
|
@MatsJohansen87 could you check why this feature is not working on safari? On chrome it works fine |
|
I think i found an elegant way to move the focus logic to the searchbar component itself. I also changed my mind about the idea to change the active element instead of increasing or decreasing the numbers in number and date inputs and think it's more intuitive like this. So i also implemented that. |
timakro
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job on getting rid of two props on the input components and moving some of the logic to search bar. I think we could also move the remaining search bar code out of the input components by using capture phase event handlers. See my comments on the code for the detailed suggestions.
| function onsubmit(event: SubmitEvent): void { | ||
| event.preventDefault(); | ||
| function addItem(): void { | ||
| if (!formVlaid) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of computing validity yourself use the return value of reportValidity() here. This will include validation of built-in HTML attributes like required, min, max and the custom errors you set with setCustomValidity. Right now for example the min HTML attribute does not work and it is possible to add body weight rage -40 through -10 in the demo.
| function validateForm(value: string | null): boolean { | ||
| input.setCustomValidity(""); | ||
| if (!value) { | ||
| input.setCustomValidity(translate("cannot_be_empty")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment on NumberInputComponent. You could use required HTML attribute instead of custom validation.
| let { | ||
| element, | ||
| inSearchBar = false, | ||
| resetToEmptySearchBar = () => {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To decouple this from the search bar I think it would be nicer to expose an event handler onItemAdded here and then register the callback from outside:
<NumberInputComponent onItemAdded={resetToEmptySearchBar}>| function onkeydown(event: KeyboardEvent) { | ||
| if (inSearchBar === false) return; | ||
| if (event.key === "Enter") { | ||
| addItem(); | ||
| } | ||
| if (event.key === "ArrowUp" || event.key === "ArrowDown") { | ||
| event.preventDefault(); | ||
| } | ||
| } | ||
| function onfocusin(event: FocusEvent) { | ||
| if (!inSearchBar) return; | ||
| // toInput can not be reached by tab when the focus is outside the form, | ||
| // so this can handle the focus via mouse click instead of using another event listener | ||
| if (event.target === toInput) return; | ||
| const relatedTargetOutside = | ||
| event.relatedTarget instanceof Node && | ||
| !form.contains(event.relatedTarget); | ||
| if (relatedTargetOutside) { | ||
| fromInput.focus(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of handling these in the input components could you try my suggestion of handling them completely from the search bar using capture phase event handlers (https://svelte.dev/tutorial/svelte/capturing)?
For the enter key you can expose addItem to the outside.
The arrow keys are already handled from the outside if you now also call event.preventDefault() during the capture phase the input won't see the arrow key event so no need to ignore it here.
I'm not 100% sure about the focus logic but it seems it is already partially handled outside. I think it would be fine if you drill down to the first input element with a smart query selector from the outside and just focus that.
| const onclick = (): void => { | ||
| queryModified.set(false); | ||
| window.dispatchEvent(new CustomEvent("lens-search-triggered")); | ||
| window.dispatchEvent(new CustomEvent("reset-all-searchbar-inputs")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently only NumberInputComponent seems to respect this. Do we even need this as when search button is pressed the search bar should loose focus and thus all inputs should be destroyed and therefore their contents reset?
| return index; | ||
| }; | ||
| let searchBarInputHasFoucs = $state(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| let searchBarInputHasFoucs = $state(true); | |
| let searchBarInputHasFocus = $state(true); |
| let focusedListItem = optionElements.find( | ||
| (element) => element && element.matches(":focus-within"), | ||
| ); | ||
| if (focusedListItem) { | ||
| focusedItemIndex = optionElements.indexOf(focusedListItem); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like something that could better go on the input component like
<NumberInputComponent onfocusin={() => focusedItemIndex = myIndex}>If you add a capture phase event handler onfocusincapture on the input components like I suggested it would go in there I suppose.
patrickskowronekdkfz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except some of the comments of @timakro the rest is fine
Description
Add input fields to Search bar
Related Issue
#498
How Has This Been Tested?
UI user test